extends NodeState

@export var player: Player

const GROUNDED_DURATION := 0.4

# 收击方向
var direction: Vector2 = Vector2.ZERO
var velocity: Vector2 = Vector2.ZERO
var height := 0.0
var height_speed := 0.0
var is_on_ground: bool


func _on_process(delta : float) -> void:
	player.position += velocity * delta
	process_knockback()
	if not is_on_ground:
		process_air_time(delta)



func _on_enter() -> void:
	is_on_ground = false
	# 进入时不允许再接收伤害
	player.damageReceiver.set_deferred("monitorable", false)

	set_height()
	process_animation()
	process_affected()




func _on_exit() -> void:
	player.damageReceiver.set_deferred("monitorable", true)



func set_height():
	if player.is_in_air():
		height = absf(player.characterSprite.position.y)
		height_speed = player.knockdown_intensity
	else:
		height = 0.0
		height_speed = player.knockdown_intensity



func process_animation():
	if player.is_in_air():
		player.animationPlayer.play(Player.ANIMATION_HURT_AIR)
	else:
		player.animationPlayer.play(Player.ANIMATION_HURT_KNOCKDOWN)



# 受到攻击时的效果
func process_affected():
	var emit_direction := player.take_damage_emit_direction()
	if emit_direction == null:
		return
	direction = Vector2.RIGHT if emit_direction.x > 0 else Vector2.LEFT
	velocity = direction * player.knockback_intensity



func process_knockback():
	if height < 0.01:
		velocity = Vector2.ZERO



func process_air_time(delta: float):
	player.characterSprite.position = Vector2.UP * height

	height += height_speed * delta
	if height < 0.0:
		height = 0.0
		is_on_ground = true
		# 高度为0表示已落地，此时显示躺地动画，躺一段时间后再起身
		player.animationPlayer.play(Player.ANIMATION_GROUNDED)
		await get_tree().create_timer(GROUNDED_DURATION).timeout
		transition_state(Player.STATE_LAND)
	else:
		height_speed -= player.gravity * delta
